# -*- coding: utf-8 -*-

"""
A sample calculator using pltgui
By Dr Jie Zheng, 2023-09-30
"""


import matplotlib.pyplot as plt
import pltgui


# First, design the interface
# ┏━━━━━━━━━━━━━━━━━━━━┓
# ┃┌────────────┐┌─┐┌─┐┃
# ┃│      123.45││=││C│┃
# ┃└────────────┘└─┘└─┘┃
# ┃┌───┐┌───┐┌───┐┌───┐┃
# ┃│ 7 ││ 8 ││ 9 ││ ÷ │┃
# ┃└───┘└───┘└───┘└───┘┃
# ┃┌───┐┌───┐┌───┐┌───┐┃
# ┃│ 4 ││ 5 ││ 6 ││ × │┃
# ┃└───┘└───┘└───┘└───┘┃
# ┃┌───┐┌───┐┌───┐┌───┐┃
# ┃│ 1 ││ 2 ││ 3 ││ − │┃
# ┃└───┘└───┘└───┘└───┘┃
# ┃┌───┐┌───┐┌───┐┌───┐┃
# ┃│ ± ││ 0 ││ . ││ + │┃
# ┃└───┘└───┘└───┘└───┘┃
# ┗━━━━━━━━━━━━━━━━━━━━┛


class calc:
    """Class calculator
    """
    
    def __init__(self):
        """Init the object
        """
        self._text_ = ""
        self.num = False
        self.op = ""
        self.last = 0.0

    @property
    def text(self):
        """Property text, keep the display same as internal value"""
        return self._text_
    
    @text.setter
    def text(self, t):
        self._text_ = t
        self.lbl_text.set_text(t)
        
    def clear(self):
        """Clear all
        """
        self.text = "0"
        self.num = False
        self.op = ""
    
    def result(self):
        """Compute"""
        self.num = False
        val = float(self.text)
        if self.op == "+":
            res = self.last + val
        elif self.op == "-":
            res = self.last - val
        elif self.op == "*":
            res = self.last * val
        elif self.op == "/":
            res = self.last / val
        else:
            res = val
        self.last = res
        self.op = ""
        self.text = f"{res:.6f}".strip("0")
    
    def on_click(self, btn):
        """A default button click handler"""
        n = btn.cmd
        if n in "0123456789.":
            if self.num:
                if not (n == '.' and '.' in self.text):
                    self.text = self.text + n
            else:
                self.text = n
                self.num = True
        elif n == "^":
            if self.text.startswith("-"):
                self.text = self.text[1:]
            else:
                self.text = "-" + self.text
        elif n in "+-*/=":    
            self.result()
            self.op = n
        elif n == "C":
            self.clear()
        else:
            pass

    def run(self):
        """Create interface and run"""
        # create the figure and the controler
        fig = plt.figure(figsize=(3, 4))
        ax = fig.add_axes([0, 0, 1, 1])
        ctl = pltgui.i_btn_ctl(ax, defa_btn_action=self.on_click)
        btn_color = "gray"
        # buttons
        self.btn_1 = ctl.add_btn(1, 2, 0.8, 0.8, btn_color, "1", "1")
        self.btn_2 = ctl.add_btn(2, 2, 0.8, 0.8, btn_color, "2", "2")
        self.btn_3 = ctl.add_btn(3, 2, 0.8, 0.8, btn_color, "3", "3")
        self.btn_4 = ctl.add_btn(1, 3, 0.8, 0.8, btn_color, "4", "4")
        self.btn_5 = ctl.add_btn(2, 3, 0.8, 0.8, btn_color, "5", "5")
        self.btn_6 = ctl.add_btn(3, 3, 0.8, 0.8, btn_color, "6", "6")
        self.btn_7 = ctl.add_btn(1, 4, 0.8, 0.8, btn_color, "7", "7")
        self.btn_8 = ctl.add_btn(2, 4, 0.8, 0.8, btn_color, "8", "8")
        self.btn_9 = ctl.add_btn(3, 4, 0.8, 0.8, btn_color, "9", "9")
        self.btn_0 = ctl.add_btn(2, 1, 0.8, 0.8, btn_color, "0", "0")
        self.btn_dt = ctl.add_btn(3, 1, 0.8, 0.8, btn_color, ".", ".")
        self.btn_pm = ctl.add_btn(1, 1, 0.8, 0.8, btn_color, "$\\pm$", "^")
        self.btn_add = ctl.add_btn(4, 1, 0.8, 0.8, btn_color, "$+$", "+")
        self.btn_sub = ctl.add_btn(4, 2, 0.8, 0.8, btn_color, "$-$", "-")
        self.btn_tms = ctl.add_btn(4, 3, 0.8, 0.8, btn_color, "$\\times$", "*")
        self.btn_div = ctl.add_btn(4, 4, 0.8, 0.8, btn_color, "$\\div$", "/")
        self.btn_clr = ctl.add_btn(3, 5, 0.8, 0.8, btn_color, "$C$", "C")
        self.btn_res = ctl.add_btn(4, 5, 0.8, 0.8, btn_color, "$=$", "=")
        # text of results
        self.lbl_text = ax.text(2.4, 5, "", ha="right", va="center")
        # display and work
        ctl.set_axis_lim()
        plt.ion()
        ctl.action_loop()
        plt.ioff()
    
if __name__ == "__main__":
    # create an anonymous object and run the calculator
    calc().run()

    
    